package com.heima.article.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.HotArticleService;
import com.heima.common.cache.CacheService;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.vos.HotArticleVo;
import com.heima.model.common.enums.ArticleConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class HotArticleServiceImpl implements HotArticleService {
    @Autowired
    private CacheService cacheService;

    @Autowired
    private ApArticleMapper apArticleMapper;

    @Override
    public void computeHotArticle() {
        // 1.查询五天内的文章
        LocalDateTime dayParam = LocalDateTime.now().minusDays(5);
        List<ApArticle> articleByLast5days = apArticleMapper.findArticleListByLast5days(dayParam);

        if (CollectionUtils.isEmpty(articleByLast5days)) {
            log.info("近五天没有文章");
            return;
        }

        // 2.计算分值  hotArticleVos.getScore文章分值
        List<HotArticleVo> hotArticleVos = computeScore(articleByLast5days);
        //CollectionUtil.groupByField()分组
        List<List<HotArticleVo>> groupList = CollectionUtil.groupByField(hotArticleVos, "channelId");

        if (CollectionUtils.isEmpty(groupList)) {
            log.warn("分组为空");
            return;
        }
        //遍历排序
        for (List<HotArticleVo> vos : groupList) {
            if (CollectionUtils.isEmpty(vos)) {
                return;
            }
            Integer channelId = vos.get(0).getChannelId();
            //频道使用
            sortAndCaching(vos, channelId.toString());
            System.out.println(vos.toString());
        }

        //给首页使用
        sortAndCaching(hotArticleVos, ArticleConstants.DEFAULT_TAG);
        System.out.println(hotArticleVos);
    }

    private void sortAndCaching(List<HotArticleVo> vos, String channelId) {
        //1.排序
        List<HotArticleVo> voList = vos
                .stream()
                .sorted(new Comparator<HotArticleVo>() {
                    @Override
                    public int compare(HotArticleVo o1, HotArticleVo o2) {
                        Integer scoreO1 = o1.getScore();
                        Integer scoreO2 = o2.getScore();
                        return scoreO2 - scoreO1;
                    }
                }).collect(Collectors.toList());

        //2.截取30条
        if (voList.size() > 30) {
            voList = voList.subList(0, 30);
        }

        //3.写入缓存
        cacheService.set(ArticleConstants.HOT_ARTICLE_FIRST_PAGE + channelId, JSON.toJSONString(voList));
    }


    private List<HotArticleVo> computeScore(List<ApArticle> articleByLast5days) {
        if (CollectionUtils.isEmpty(articleByLast5days)) {
            return new ArrayList<>();
        }

        ArrayList<HotArticleVo> hotArticleVos = new ArrayList<>();

        for (ApArticle articleByLast5day : articleByLast5days) {
            if (CollectionUtils.isEmpty(articleByLast5days)) {
                continue;
            }
            int score = 0;
            Integer views = articleByLast5day.getViews();//阅读1
            Integer likes = articleByLast5day.getLikes();//点赞3
            Integer comment = articleByLast5day.getComment();//评论5
            Integer collection = articleByLast5day.getCollection();//收藏8

            if (views != null) {
                score += views;
            }
            if (likes != null) {
                score += ArticleConstants.HOT_ARTICLE_LIKE_WEIGHT * likes;
            }
            if (comment != null) {
                score += ArticleConstants.HOT_ARTICLE_COMMENT_WEIGHT * comment;
            }
            if (collection != null) {
                score += ArticleConstants.HOT_ARTICLE_COLLECTION_WEIGHT * collection;
            }

            HotArticleVo hotArticleVo = new HotArticleVo();
            BeanUtils.copyProperties(articleByLast5day, hotArticleVo);
            hotArticleVo.setScore(score);

            hotArticleVos.add(hotArticleVo);
        }
        return hotArticleVos;
    }


}
